package pbandk

import com.google.protobuf_test_messages.proto3.TestMessagesProto3
import pbandk.testpb.ForeignEnum
import pbandk.testpb.MessageWithMap
import pbandk.testpb.TestAllTypesProto3
import kotlin.test.Test
import kotlin.test.assertTrue

class JvmMapTest {
    @Test
    fun testMap() {
        val testMap = mapOf("1" to "a", "2" to "b", "blahblahblah" to "5000")
        // Generate a Java version of the proto and deserialize Kotlin version and vice-versa
        val builtJavaObj = pbandk.testpb.java.Test.MessageWithMap.newBuilder().putAllMap(testMap).build()
        val builtKotlinObj = MessageWithMap(testMap)
        pbandkJavaRoundtripTest(builtJavaObj, builtKotlinObj, MessageWithMap.Companion)
    }

    @Test
    fun testMapDecodeType() {
        val messageWithMap = MessageWithMap(mapOf("1" to "a", "2" to "b", "blahblahblah" to "5000"))
        val deserialized = MessageWithMap.decodeFromByteArray(messageWithMap.encodeToByteArray())

        // Check that map-with-size
        assertTrue(deserialized.map is MessageMap)
    }

    @Test
    fun testMapDefaultValues() {
        val builtJavaObj = TestMessagesProto3.TestAllTypesProto3.newBuilder()
            .putAllMapStringForeignEnum(
                mapOf(
                    "11" to TestMessagesProto3.ForeignEnum.FOREIGN_FOO,
                    "99" to TestMessagesProto3.ForeignEnum.FOREIGN_BAR
                )
            )
            .putAllMapInt32Int32(
                mapOf(
                    11 to 0,
                    99 to 1
                )
            )
            .putAllMapStringString(
                mapOf(
                    "11" to "",
                    "99" to "foo"
                )
            )
            .build()

        val builtKotlinObj = TestAllTypesProto3(
            mapStringForeignEnum = mapOf(
                "11" to ForeignEnum.FOREIGN_FOO,
                "99" to ForeignEnum.FOREIGN_BAR
            ),
            mapInt32Int32 = mapOf(
                11 to 0,
                99 to 1
            ),
            mapStringString = mapOf(
                "11" to "",
                "99" to "foo"
            )
        )

        pbandkJavaRoundtripTest(
            builtJavaObj,
            builtKotlinObj,
            TestAllTypesProto3.Companion,
            // protobuf-java and pbandk encoded representations will be different because protobuf-java serializes map
            // entries with default values whereas pbandk omits them. Both approaches are allowed by the proto3 spec. So
            // even though sizes and bytes will be different, protobuf-java and pbandk should still be able to read the
            // bytes generated by the other library.
            encodingsMustBeEqual = false,
        )
    }
}